﻿// Original author contact info: Owen Emlen (owene_1998@yahoo.com)
// Note: other individuals may also have contributed to this code
// Project hosted on CodePlex.com as of 1/10/2009 at http://wpfimageviewer.codeplex.com
using System;
using System.IO;
using System.Linq;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text;
using BrainTechLLC;
using BrainTechLLC.WPF;
using System.Windows.Data;
using System.Diagnostics;
using System.Windows.Controls;
using System.Windows.Threading;
using System.Windows;
using System.Collections.Specialized;
using DirectoryViewModels;
using System.ComponentModel;

namespace BrainTechLLC.FolderExplorer
{
    public partial class FolderExplorerControl : UserControl
    {
        public FolderViewModel _root;

        public static readonly DependencyProperty RootFolderProperty =
            DependencyProperty.Register("RootFolder", typeof(FolderViewModel), typeof(FolderExplorerControl), new PropertyMetadata(new FolderViewModel(null, null) { FullPath = @"C:\" }, OnRootFolderPropertyChanged));

        public static readonly DependencyProperty NoSizesProperty =
            DependencyProperty.Register("NoSizes", typeof(bool), typeof(FolderExplorerControl), new PropertyMetadata(false, OnNoSizesPropertyChanged));

        public static readonly DependencyProperty DirectoriesToExamineViewModelProperty =
            DependencyProperty.Register("DirectoriesToExamineViewModel", typeof(DirectoriesToExamineViewModel), typeof(FolderExplorerControl), new PropertyMetadata(null, OnDirectoriesToExamineViewModelPropertyChanged));

        public static readonly DependencyProperty ShowFilesAndFoldersProperty =
            DependencyProperty.Register("ShowFilesAndFolders", typeof(bool), typeof(FolderExplorerControl), new PropertyMetadata(false, OnShowFilesAndFoldersPropertyChanged));

        public static readonly DependencyProperty TextSizeProperty =
            DependencyProperty.Register("TextSize", typeof(double), typeof(FolderExplorerControl), new PropertyMetadata(9.0, OnTextSizePropertyChanged));

        public double TextSize
        {
            get { return (double)GetValue(TextSizeProperty); }
            set { SetValue(TextSizeProperty, value); }
        }

        private static void OnTextSizePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            FolderExplorerControl source = d as FolderExplorerControl;
            double v = (double)e.NewValue;
            source.UpdateTextSize(v);
        }

        private void UpdateTextSize(double val)
        {
            UpdateUI();
        }

        public void UpdateUI()
        {
            showFolders.TextSize = TextSize;
            showFiles.TextSize = TextSize;
        }

        public bool ShowFilesAndFolders
        {
            get { return (bool)GetValue(ShowFilesAndFoldersProperty); }
            set { SetValue(ShowFilesAndFoldersProperty, value); }
        }

        private static void OnShowFilesAndFoldersPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            FolderExplorerControl source = d as FolderExplorerControl;
            source.UpdateShowFilesAndFolders((bool)e.NewValue, (bool)e.OldValue);
        }

        private void UpdateShowFilesAndFolders(bool f, bool old)
        {
            if (rightGrid != null)
            {
                rightGrid.Visibility = f ? System.Windows.Visibility.Visible : System.Windows.Visibility.Collapsed;
                rightGridSplitter.Visibility = f ? System.Windows.Visibility.Visible : System.Windows.Visibility.Collapsed;
            }
        }

        public bool NoSizes
        {
            get { return (bool)GetValue(NoSizesProperty); }
            set { SetValue(NoSizesProperty, value); }
        }

        private static void OnNoSizesPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            FolderExplorerControl source = d as FolderExplorerControl;
            source.UpdateNoSizes((bool)e.NewValue, (bool)e.OldValue);
        }

        private void UpdateNoSizes(bool f, bool old)
        {

        }

        public DirectoriesToExamineViewModel DirectoriesToExamineViewModel
        {
            get { return (DirectoriesToExamineViewModel)GetValue(DirectoriesToExamineViewModelProperty); }
            set { SetValue(DirectoriesToExamineViewModelProperty, value); }
        }

        public FolderViewModel RootFolder
        {
            get { return (FolderViewModel)GetValue(RootFolderProperty); }
            set { _root = value; SetValue(RootFolderProperty, value); }
        }

        private static void OnRootFolderPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            FolderExplorerControl source = d as FolderExplorerControl;
            source.UpdateRootFolder(e.NewValue as FolderViewModel, e.OldValue as FolderViewModel);
        }

        private void UpdateRootFolder(FolderViewModel f, FolderViewModel old)
        {
            if (old != null)
            {
                f.SubfoldersPopulated -= f_SubfoldersPopulated;
                f.ClearSubfolders -= f_ClearSubfolders;
                f.PropertyChanged -= f_PropertyChanged;
                UnwireSubfolders(f);
            }

            tvRoot.Header = f.FullPath;
            RootFolder = f;

            Binding b = new Binding("RootFolder");
            b.Mode = BindingMode.OneWay;
            b.Source = this;
            treeView1.SetBinding(TreeView.ItemsSourceProperty, b);
            treeView1.DataContext = RootFolder;
            tvRoot.DataContext = RootFolder;

            if (f != null)
            {
                f.IsExpanded = true;
            }

            if (f != null)
            {
                f.PropertyChanged += new PropertyChangedEventHandler(f_PropertyChanged);
                f.ClearSubfolders += new EventHandler(f_ClearSubfolders);
                f.SubfoldersPopulated += new EventHandler(f_SubfoldersPopulated);
                WireSubfolders(f);
            }

            Dispatcher.BeginInvoke(new VoidDelegate(() => SizeBorder(border, AllGrids)), DispatcherPriority.Render);

            Dispatcher.BeginInvoke(new VoidDelegate(() =>
            {
                if (rightGrid != null)
                {
                    rightGrid.Visibility = ShowFilesAndFolders ? System.Windows.Visibility.Visible : System.Windows.Visibility.Collapsed;
                    rightGridSplitter.Visibility = ShowFilesAndFolders ? System.Windows.Visibility.Visible : System.Windows.Visibility.Collapsed;
                }
            }));
        }

        void f_SubfoldersPopulated(object sender, EventArgs e)
        {
            FolderViewModel f = sender as FolderViewModel;
            WireSubfolders(f);
        }

        private void WireSubfolders(FolderViewModel f)
        {
            if (f.SubFoldersCached != null)
            {
                for (int n = 0; n < f.SubFoldersCached.Count; n++)
                {
                    var folder = f.SubFoldersCached[n];
                    folder.PropertyChanged += new PropertyChangedEventHandler(f_PropertyChanged);
                    folder.ClearSubfolders += new EventHandler(f_ClearSubfolders);
                    folder.SubfoldersPopulated += new EventHandler(f_SubfoldersPopulated);
                }
            }
        }

        void f_ClearSubfolders(object sender, EventArgs e)
        {
            FolderViewModel f = sender as FolderViewModel;
            UnwireSubfolders(f);
        }

        private void UnwireSubfolders(FolderViewModel f)
        {
            if (f.SubFoldersCached != null)
            {
                foreach (var folder in f.SubFoldersCached)
                {
                    folder.SubfoldersPopulated -= f_SubfoldersPopulated;
                    folder.ClearSubfolders -= f_ClearSubfolders;
                    folder.PropertyChanged -= f_PropertyChanged;
                }
            }
        }

        void f_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            //if (e.PropertyName == "StartingSelection")
            //{
            //    FolderViewModel f = sender as FolderViewModel;
            //    SelectFoldersStart.RaiseEvent(this, f);
            //}
            //else if (e.PropertyName == "EndingSelection")
            //{
            //    FolderViewModel f = sender as FolderViewModel;
            //    SelectFoldersEnd.RaiseEvent(this, f);
            //}
            //Console.WriteLine(string.Format("FolderViewModel {0}: {1}", f.Name, e.PropertyName));
        }

        private static void OnDirectoriesToExamineViewModelPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            FolderExplorerControl source = d as FolderExplorerControl;
            DirectoriesToExamineViewModel v = e.NewValue as DirectoriesToExamineViewModel;
            DirectoriesToExamineViewModel vOld = e.OldValue as DirectoriesToExamineViewModel;
            source.UpdateDirectoriesToExamineViewModel(vOld, v);
        }

        private void UpdateDirectoriesToExamineViewModel(DirectoriesToExamineViewModel viewModelOld, DirectoriesToExamineViewModel viewModel)
        {
            if (viewModel != viewModelOld)
            {
                if (viewModelOld != null)
                {
                    viewModelOld.CollectionChanged -= viewModel_CollectionChanged;

                    foreach (var vm in viewModelOld)
                    {
                        vm.PropertyChanged -= vm_PropertyChanged;
                    }
                }

                if (viewModel != null)
                {
                    viewModel.CollectionChanged += new NotifyCollectionChangedEventHandler(viewModel_CollectionChanged);

                    foreach (var vm in viewModel)
                    {
                        vm.PropertyChanged += new PropertyChangedEventHandler(vm_PropertyChanged);
                    }
                }
                DirectoriesToExamineViewModel = viewModel;
                RootFolder.DirectoriesToExamineViewModel = viewModel;
            }
        }

        void vm_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            DirectoryToExamineViewModel vm = sender as DirectoryToExamineViewModel;

            if (e.PropertyName == "StartingSelection")
            {
                //FolderViewModel f = sender as FolderViewModel;
                SelectFoldersStart.RaiseEvent(this, null);
            }
            else if (e.PropertyName == "EndingSelection")
            {
                //FolderViewModel f = sender as FolderViewModel;
                SelectFoldersEnd.RaiseEvent(this, null);
            }
            //Console.WriteLine(string.Format("{0}: {1}", vm.Directory, e.PropertyName));
        }

        void viewModel_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
        {
            //Console.WriteLine("Collection Changed");
        }
    }
}
